package org.example;



import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.io.File;
import java.util.List;

/**
 * Mybatis-Plus 代码生成器 Maven插件版，基于Mybatis-Plus代码生成器项目
 * 主执行器 MainMojo 类
 * @author LiuZijian
 * 2021-01-21
 */
@Mojo(name = "genCode", threadSafe = true)
public class MainMojo extends AbstractMojo {

    @Parameter(name = "url")
    private String url;

    @Parameter(name = "username")
    private String username;

    @Parameter(name = "password")
    private String password;

    @Parameter(name = "tables")
    private List<String> tables;

    @Parameter(name = "author")
    private String author;

    @Parameter(name = "packageParentPath")
    private String packageParentPath;

    @Parameter(name = "servicePackageName")
    private String servicePackageName;
    @Parameter(name = "serviceImplPackageName")
    private String serviceImplPackageName;
    @Parameter(name = "mapperPackageName")
    private String mapperPackageName;
    @Parameter(name = "xmlPackageName")
    private String xmlPackageName;
    @Parameter(name = "controllerPackageName")
    private String controllerPackageName;
    @Parameter(name = "entityPackageName")
    private String entityPackageName;

    @Parameter(name = "driver", defaultValue = "com.mysql.jdbc.Driver")
    private String driver;

    @Parameter(defaultValue = "${session}", readonly = true)
    private MavenSession mavenSession;

    @Parameter(name = "outputPath")
    private String outputPath;

    @Parameter(name = "activeRecord", defaultValue = "false")
    private Boolean activeRecord;

    @Parameter(name = "lombok", defaultValue = "true")
    private Boolean lombok;

    @Parameter(name = "tableNamingStrategy", defaultValue = "underline_to_camel")
    private NamingStrategy tableNamingStrategy;

    @Parameter(name = "fieldNamingStrategy", defaultValue = "underline_to_camel")
    private NamingStrategy fieldNamingStrategy;

    @Parameter(name = "tablePrefix")
    private String tablePrefix;

    @Override
    public void execute() throws MojoExecutionException {

        getLog().info(" ============ MyBatis-Plus 代码生成器 =============");

        if (isEmpty(outputPath)) {
            outputPath = mavenSession.getExecutionRootDirectory() + File.separator + ".generator";
        }

        this.validater();

        this.generator();

        getLog().info("======================成功生成！================");
        getLog().info("生成位置：" + outputPath);
    }


    private void validater() throws MojoExecutionException {
        if (isEmpty(url)) {
            getLog().error("url 不能为空");
            throw new MojoExecutionException("url 不能为空");
        }
        if (isEmpty(username)) {
            getLog().error("username 不能为空");
            throw new MojoExecutionException("username 不能为空");
        }
        if (isEmpty(password)) {
            getLog().error("password 不能为空");
            throw new MojoExecutionException("password 不能为空");
        }


        if (tables == null || tables.size() == 0) {
            getLog().error("tables 不能为空");
            throw new MojoExecutionException("tables 不能为空");
        }
        if (isEmpty(packageParentPath)) {
            getLog().error("packageParentPath 不能为空");
            throw new MojoExecutionException("packageParentPath 不能为空");
        }
    }


    private void generator() throws MojoExecutionException {
        try {
            AutoGenerator generator = new AutoGenerator();

            GlobalConfig global = new GlobalConfig();
            global.setOutputDir(outputPath);
            global.setAuthor(author);
            global.setOpen(false);
            global.setBaseColumnList(true);
            global.setDateType(DateType.ONLY_DATE);
            global.setBaseResultMap(true);
            global.setActiveRecord(activeRecord);
            global.setFileOverride(true);
            generator.setGlobalConfig(global);

            DataSourceConfig dataSourceConfig = new DataSourceConfig();
            dataSourceConfig.setUrl(url);
            dataSourceConfig.setDriverName(driver);
            dataSourceConfig.setUsername(username);
            dataSourceConfig.setPassword(password);
            generator.setDataSource(dataSourceConfig);

            PackageConfig packageConfig = new PackageConfig();
            packageConfig.setParent(packageParentPath);

            if (!isEmpty(servicePackageName)) {
                packageConfig.setService(servicePackageName);
            }

            if (!isEmpty(serviceImplPackageName)) {
                packageConfig.setServiceImpl(serviceImplPackageName);
            }

            if (!isEmpty(mapperPackageName)) {
                packageConfig.setMapper(mapperPackageName);
            }

            if (!isEmpty(xmlPackageName)) {
                packageConfig.setXml(xmlPackageName);
            }

            if (!isEmpty(controllerPackageName)) {
                packageConfig.setController(controllerPackageName);
            }

            if (!isEmpty(entityPackageName)) {
                packageConfig.setEntity(entityPackageName);
            }

            generator.setPackageInfo(packageConfig);

            StrategyConfig strategy = new StrategyConfig();

            strategy.setNaming(tableNamingStrategy);
            strategy.setColumnNaming(fieldNamingStrategy);
            strategy.setEntityLombokModel(lombok);
            strategy.setRestControllerStyle(true);
            strategy.setInclude(tables.toArray(new String[tables.size()]));
            strategy.setControllerMappingHyphenStyle(true);
            strategy.setEntityTableFieldAnnotationEnable(true);
            if (!isEmpty(tablePrefix)) {
                strategy.setTablePrefix(tablePrefix);
            }

            generator.setStrategy(strategy);
            generator.setTemplateEngine(new FreemarkerTemplateEngine());
            generator.execute();

        } catch (Exception e) {
            getLog().error("生成时出错！");
            throw new MojoExecutionException(e.getMessage());
        }

    }


    private boolean isEmpty(String s) {
        return s == null || "".equals(s.trim());
    }
}



